<?php

/**
 * 框架应用程序类
 * Created by PhpStorm.
 * User: simon_min@aliyun.com
 * Date: 2016/11/5
 * Time: 12:47
 */
final class Application
{
    /**
     * 应用程序类执行方法run
     */
    public static function run()
    {
        self::_init();
        set_error_handler(array(__CLASS__, 'error'));
        register_shutdown_function(array(__CLASS__, 'fatal_error'));
        self::_user_import();
        self::_set_url();
        spl_autoload_register(array(__CLASS__, '_autoload'));
        self::_create_demo_action();
        self::_app_run();
    }

    /**
     *实例化应用控制器
     */
    private static function _app_run()
    {
        $controller = isset($_GET['c']) ? $_GET['c'] : 'Index';
        $action = isset($_GET['a']) ? $_GET['a'] : 'index';
        define('CONTROLLER', $controller);
        define('ACTION', $action);
        $controller .= 'Controller';
        if (class_exists($controller)) {
            $obj = new $controller();
            if (!method_exists($obj, $action)) {
                if (method_exists($obj, '__empty')) {
                    $obj->__empty();
                } else {
                    halt($controller . '控制器中' . $action . '方法不存在');
                }
            } else {
                $obj->$action();
            }
        } else {
            $emptyobj = new EmptyController();
            $emptyobj->index();
        }
    }

    /**
     * 创建系统默认控制器
     */
    private static function _create_demo_action()
    {
        $path = APP_CONTROLLER_PATH . '/IndexController.class.php';

        $str = <<<str
<?php

class IndexController extends Controller
{
    public function index()
    {
        echo 'Framework!';
    }
}
str;
        is_file($path) || file_put_contents($path, $str);
    }

    /**
     * 自动类文件加载
     */
    private static function _autoload($className)
    {
        switch (true) {
            //判断是否是控制器
            case strlen($className) > 10 && substr($className, -10) == 'Controller':
                $path = APP_CONTROLLER_PATH . '/' . $className . '.class.php';
                //未找到控制器时，加载空操作控制器
                if (!is_file($path)) {
                    $emptyPaht = APP_CONTROLLER_PATH . '/EmptyController.class.php';
                    if (is_file($emptyPaht)) {
                        include $emptyPaht;
                        return;
                    } else {
                        halt($path . '控制器未找到');
                    }
                }
                include $path;
                break;
            case strlen($className) > 5 && substr($className, -5) == 'Model':
                $path = COMMON_MODEL_PATH . '/' . $className . '.class.php';
                include $path;
                break;
            //加载工具类中的文件
            default:
                $path = TOOL_PATH . '/' . $className . '.class.php';
                if (!is_file($path)) halt($path . '类未找到');
                include $path;
                break;
        }
    }

    /**
     * 设置外部路径
     */
    private static function _set_url()
    {
        $path = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];
        $path = str_replace('\\', '/', $path);
        define('__APP__', $path);
        define('__ROOT__', dirname(__APP__));
        //应用模板目录
        define('__TPL__', __ROOT__ . '/' . APP_NAME . '/Tpl');
        define('__PUBLIC__', __TPL__ . '/Public');
    }

    /**
     * 用户配置自定义文件按需加载,目标目录为Common/Lib
     */
    public static function _user_import()
    {
        $fileArr = C('AUTO_LOAD_FILE');
        if (!empty($fileArr) && is_array($fileArr)) {
            foreach ($fileArr as $v) {
                require_once COMMON_LIB . '/' . $v;
            }
        }
    }

    /**
     * Register a function for execution on shutdown
     */
    public static function fatal_error()
    {
        if ($e = error_get_last()) {
            self::error($e['type'], $e['message'], $e['file'], $e['line']);
        }
    }

    /**
     * 用户自定义的错误处理函数
     */
    public static function error($errno, $error, $file, $line)
    {
        switch ($errno) {
            case E_ERROR:
            case E_PARSE:
            case E_CORE_ERROR:
            case E_COMPILE_ERROR:
            case E_USER_ERROR:
                $msg = $error . $file . " 第{$line}行";
                halt($msg);
                break;
            case E_STRICT:
            case E_USER_WARNING:
            case E_USER_NOTICE:
            default:
                if (DEBUG) {
                    include DATA_PATH . '/Tpl/notice.html';
                }
                break;
        }
    }

    /**
     * 初始化框架
     */
    public static function _init()
    {
        //加载配置项,系统配置项
        C(include CONFIG_PATH . '/config.php');

        //加载公共配置项
        $commonPath = COMMON_CONFIG_PATH . '/config.php';
        $commonConfig = <<<str
<?php

return array(
    //配置项 => 配置值
);
str;
        is_file($commonPath) || file_put_contents($commonPath, $commonConfig);
        C(include $commonPath);

        //加载用户配置项
        $userPath = APP_CONFIG_PATH . '/config.php';
        $userConfig = <<<str
<?php

return array(
    //配置项 => 配置值
);
str;
        is_file($userPath) || file_put_contents($userPath, $userConfig);
        C(include $userPath);

        //设置默认时区
        date_default_timezone_set(C('DEFAULT_TIME_ZONE'));
        //是否开启session
        C('SESSION_AUTO_START') && session_start();
    }
}